package com.jzo2o.health.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.common.expcetions.BadRequestException;
import com.jzo2o.common.expcetions.DBException;
import com.jzo2o.health.mapper.ReservationSettingMapper;
import com.jzo2o.health.model.domain.ReservationSetting;
import com.jzo2o.health.model.dto.request.ReservationSettingUpsertReqDTO;
import com.jzo2o.health.model.dto.response.ReservationDateResDTO;
import com.jzo2o.health.model.dto.response.ReservationSettingResDTO;
import com.jzo2o.health.model.excel.ReservationImportData;
import com.jzo2o.health.service.IReservationSettingService;
import com.jzo2o.health.util.EasyExcelUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 预约设置 服务实现类
 * </p>
 *
 * @author author
 * @since 2024-12-14
 */
@Service
public class ReservationSettingServiceImpl extends ServiceImpl<ReservationSettingMapper, ReservationSetting> implements IReservationSettingService {


    /**
     * 根据月份查询预约设置
     * @param date 月份，格式：yyyy-MM
     */
    @Override
    public List<ReservationSettingResDTO> getReservationSettingByMonth(String date) {

        // 定义日期格式，这里是年月格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        // 将年月字符串解析为 LocalDate，默认日为该月的第一天
        LocalDate localDate = LocalDate.parse(date + "-01", formatter);
        if (localDate != null) {
            // 获取该月的最后一天
            LocalDate endOfMonth = localDate.withDayOfMonth(localDate.lengthOfMonth());
            // 查询该月所有预约设置
            List<ReservationSetting> reservationSettings = baseMapper.selectList(new LambdaQueryWrapper<ReservationSetting>().between(ReservationSetting::getOrderDate, localDate, endOfMonth));
            // 遍历预约设置，将预约设置转换为响应对象
            return reservationSettings.stream()
                    .map(reservationSetting -> ReservationSettingResDTO.builder()
                           .date(reservationSetting.getOrderDate().format(formatter))
                            .number(reservationSetting.getNumber())
                            .reservations(reservationSetting.getReservations())
                            .build()
                    ).collect(Collectors.toList());
        }
        return null;
    }

    /**
     * 编辑预约设置
     *
     * @param reservationSettingUpsertReqDTO
     */
    @Override
    public void editNumberByDate(ReservationSettingUpsertReqDTO reservationSettingUpsertReqDTO) {
        // 获取预约日期和预约人数
        LocalDate orderDate = reservationSettingUpsertReqDTO.getOrderDate();
        Integer number = reservationSettingUpsertReqDTO.getNumber();

        if(orderDate == null || number == null){
            throw new BadRequestException("预约日期和预约人数不能为空");
        }
        // 查询预约设置
        ReservationSetting reservationSetting = baseMapper.selectOne(new LambdaQueryWrapper<ReservationSetting>()
                .eq(ReservationSetting::getOrderDate, orderDate));
        // 判断预约设置是否存在
        if (reservationSetting != null){
            // 更新预约人数
            reservationSetting.setNumber(number);
            int count = baseMapper.updateById(reservationSetting);
            if (count <= 0){
                throw new DBException("更新失败");
            }
        }else {
            // 为空插入预约设置
            reservationSetting = new ReservationSetting();
            reservationSetting.setOrderDate(orderDate);
            reservationSetting.setNumber(number);
            int count = baseMapper.insert(reservationSetting);
            if (count <= 0){
                throw new DBException("插入失败");
            }
        }
    }


    /**
     * 批量添加预约设置
     *
     * @param file
     */
    @Override
    public void batchInsert(MultipartFile file) {
        List<ReservationImportData> contentOfExcel = EasyExcelUtils.getContentOfExcel(file);
        if (contentOfExcel != null && contentOfExcel.size() > 0){
            // 遍历数据，插入数据库
            for (ReservationImportData data : contentOfExcel) {
                ReservationSettingUpsertReqDTO bean = ReservationSettingUpsertReqDTO.builder()
                        .number(data.getNumber())
                        .orderDate(LocalDate.parse(data.getDate(), DateTimeFormatter.ofPattern("yyyy-MM-dd")))
                        .build();
                if (bean.getOrderDate().isAfter(LocalDate.now()))
                    editNumberByDate(bean);
            }
        }
    }

    /**
     * 用户端查询可预约日期
     *
     * @param month
     * @return
     */
    @Override
    public ReservationDateResDTO getEnableDate(String month) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate start = LocalDate.parse(month+"-01",formatter);
        LocalDate end = start.withDayOfMonth(start.lengthOfMonth());
        if (start.isAfter(LocalDate.now())) {

        } else if (end.isBefore(LocalDate.now())) {
            return null;
        } else {
            start = LocalDate.now().plusDays(1);
        }

        List<String> availableDates = baseMapper.selectList(new LambdaQueryWrapper<ReservationSetting>()
                        .select(ReservationSetting::getOrderDate)
                        .between(ReservationSetting::getOrderDate, start, end)
                        .apply("reservations < number")
                ).stream()
                .map(item -> item.getOrderDate().toString())
                .collect(Collectors.toList());

        return ReservationDateResDTO.builder()
                .dateList(availableDates)
                .build();
    }
}
